import com.cgah.Bid
import com.cgah.Customer
import com.cgah.Listing
import com.cgah.RequestMap
import com.cgah.User;
import com.cgah.UserRole;
import com.cgah.Role;
import grails.util.Environment
import com.cgah.Constants

class BootStrap {
    // injected by Spring
    def springSecurityService;



    def init = { servletContext ->

        // NOTE: don't worry about root context. this shit seems to take care of it from /
        // S-1: A new visitor to the site can register themselves as a new user
        new RequestMap(url: '/login/*', configAttribute: Constants.IS_AUTHENTICATED_ANONYMOUSLY).save()

        //S-2: Viewing the main landing page and the listing detail page does not require that the user be logged in
        // anything else i haven't restricted is viewable. (!! DANGEROUS !!) PFT SECURITY WHATEVER
        new RequestMap(url: '/**', configAttribute: Constants.IS_AUTHENTICATED_ANONYMOUSLY).save()

        // S-2: Viewing the main landing page and the listing detail page does not require that the user be logged in
        new RequestMap(url: '/listing/list', configAttribute: Constants.IS_AUTHENTICATED_ANONYMOUSLY).save()
        new RequestMap(url: '/listing/show', configAttribute: Constants.IS_AUTHENTICATED_ANONYMOUSLY).save()
        // S-5: Create a view called "My Listings" that shows listings created by the logged in user
        new RequestMap(url: '/listing/listingForUser', configAttribute: Constants.ROLE_USER).save()
        //S-6: A logged in user can create a new listing via a simple form;
        new RequestMap(url: '/listing/create', configAttribute: Constants.ROLE_USER).save()
        new RequestMap(url: '/listing/edit', configAttribute: Constants.ROLE_USER).save()

        // S-3: Bidding on an item requires that the user be logged in
        new RequestMap(url: '/bid/create', configAttribute: Constants.ROLE_USER).save()
        // cv-3: editing a bid is strictly prohibited.
        new RequestMap(url: '/bid/edit', configAttribute: Constants.ROLE_WTFNOWAY).save()

        //S-4: Only a user with an admin role is able to view / edit customer screens created in requirements C-1 through C-4 in assignment 2
        new RequestMap(url: '/customer/*', configAttribute: Constants.ROLE_ADMIN).save()

// todo: handle the ajax posts?  do i have to worry about this?
//        new RequestMap(url: '/person/*', configAttribute: 'IS_AUTHENTICATED_REMEMBERED').save()
//        new RequestMap(url: '/post/followAjax', configAttribute: BootStrap.ROLE_USER).save()
//        new RequestMap(url: '/post/addPostAjax', configAttribute: 'ROLE_USER,IS_AUTHENTICATED_FULLY').save()

        if (Environment.current == Environment.DEVELOPMENT) {
            if (!Customer.count()) {
                // stick some roles into the DB
                def userRole = Role.findByAuthority(Constants.ROLE_USER) ?: new Role(authority: Constants.ROLE_USER).save(failOnError: true)
                def adminRole = Role.findByAuthority(Constants.ROLE_ADMIN) ?: new Role(authority: Constants.ROLE_ADMIN).save(failOnError: true)

                // create users and give them user role
                def c1 = User.findByUsername('johndoe') ?:
                    new Customer(
                            username: "johndoe",
                            emailAddress: "johndoe@test.com",
                            password: springSecurityService.encodePassword('boooya', null),
                            createdDate: new Date(),
                            enabled: true).save(failOnError: true)
                if (!c1.getAuthorities().contains(userRole)) {
                    UserRole.create(c1, userRole)
                }

                def c2 = User.findByUsername('janedoe') ?:
                    new Customer(
                            username: "janedoe",
                            emailAddress: "janedoe@test.com",
                            password: springSecurityService.encodePassword('boooya'),
                            createdDate: new Date(),
                            enabled: true).save(failOnError: true)

                if (!c2.getAuthorities().contains(userRole)) {
                    UserRole.create(c2, userRole)
                }

                // create admin and give admin rol
                def adminUser = User.findByUsername('admin') ?:
                    new User(
                            username: 'admin',
                            emailAddress: "admin@test.com",
                            password: springSecurityService.encodePassword('boooya'),
                            enabled: true).
                            save(failOnError: true)

                if (!adminUser.getAuthorities().contains(adminRole)) {
                    UserRole.create adminUser, adminRole
                }

                // user jill has no roles
                User.findByUsername('jill') ?:
                    new Customer(
                            username: "jill",
                            emailAddress: "jill@test.com",
                            password: springSecurityService.encodePassword('boooya'),
                            createdDate: new Date(),
                            enabled: true).save(failOnError: true)

                // user Bill has roles, but is NOT enabled
                def bill = User.findByUsername('bill') ?:
                    new Customer(
                            username: "bill",
                            emailAddress: "bill@test.com",
                            password: springSecurityService.encodePassword('boooya'),
                            createdDate: new Date(),
                            enabled: false).save(failOnError: true)

                if (!bill.getAuthorities().contains(adminRole)) {
                    UserRole.create(bill, adminRole)
                }
                if (!bill.getAuthorities().contains(userRole)) {
                    UserRole.create(bill, userRole)
                }


                if (!Listing.count()) {

                    Listing l1 = new Listing(name: "bling brain", startingBidPrice: 10.0, seller: c1, endDateTime: new Date() + 6, createdDateTime: new Date() - 6).save(failOnError: true);
                    new Listing(name: "silver brain", startingBidPrice: 9.0, seller: c1, endDateTime: new Date() + 5, createdDateTime: new Date() - 5).save(failOnError: true);
                    new Listing(name: "gold brain", startingBidPrice: 8.0, seller: c1, endDateTime: new Date() + 4, createdDateTime: new Date() - 4).save(failOnError: true);
                    new Listing(name: "platinum brain", startingBidPrice: 7.0, seller: c1, endDateTime: new Date() + 3, createdDateTime: new Date() - 3).save(failOnError: true);
                    new Listing(name: "copper brain", startingBidPrice: 6.0, seller: c1, endDateTime: new Date() + 2, createdDateTime: new Date() - 2).save(failOnError: true);
                    new Listing(name: "chrome brain", startingBidPrice: 5.0, seller: c1, endDateTime: new Date() + 1, createdDateTime: new Date() - 1).save(failOnError: true);
                    new Listing(name: "titanium brain", startingBidPrice: 4.0, seller: c1, endDateTime: new Date() + 2, createdDateTime: new Date() - 2).save(failOnError: true);
                    new Listing(name: "blue brain", startingBidPrice: 4.0, seller: c1, endDateTime: new Date() + 1, createdDateTime: new Date() - 1).save(failOnError: true);
                    new Listing(name: "pickled brain", startingBidPrice: 4.0, seller: c1, endDateTime: new Date() + 1, createdDateTime: new Date() - 2).save(failOnError: true);


                    Listing l2 = new Listing(name: "ballz", startingBidPrice: 10.0, seller: c2, endDateTime: new Date() + 7, createdDateTime: new Date() - 7).save(failOnError: true);
                    new Listing(name: "red ballz", startingBidPrice: 9.0, seller: c2, endDateTime: new Date() + 6, createdDateTime: new Date() - 6).save(failOnError: true);
                    new Listing(name: "blue ballz", startingBidPrice: 8.0, seller: c2, endDateTime: new Date() + 5, createdDateTime: new Date() - 5).save(failOnError: true);
                    new Listing(name: "green ballz", startingBidPrice: 7.0, seller: c2, endDateTime: new Date() + 4, createdDateTime: new Date() - 4).save(failOnError: true);
                    new Listing(name: "yellow ballz", startingBidPrice: 6.0, seller: c2, endDateTime: new Date() + 3, createdDateTime: new Date() - 3).save(failOnError: true);
                    new Listing(name: "orange ballz", startingBidPrice: 5.0, seller: c2, endDateTime: new Date() + 2, createdDateTime: new Date() - 2).save(failOnError: true);
                    new Listing(name: "black ballz", startingBidPrice: 4.0, seller: c2, endDateTime: new Date() + 1, createdDateTime: new Date() - 1).save(failOnError: true);
                    new Listing(name: "brown ballz", startingBidPrice: 3.0, seller: c2, endDateTime: new Date() + 1, createdDateTime: new Date() - 1).save(failOnError: true);
                    new Listing(name: "purple ballz", startingBidPrice: 2.0, seller: c2, endDateTime: new Date() + 2, createdDateTime: new Date() - 2).save(failOnError: true);
                    new Listing(name: "white ballz", startingBidPrice: 1.0, seller: c2, endDateTime: new Date() + 3, createdDateTime: new Date() - 3).save(failOnError: true);



                    if (!Bid.count()) {
                        new Bid(customer: c1, listing: l1, amount: 12.0f, dateTime: new Date()).save(failOnError: true);
                        new Bid(customer: c2, listing: l2, amount: 12.0f, dateTime: new Date()).save(failOnError: true);
                    }

                }
            }
        }
/*
        if (Environment.current == Environment.DEVELOPMENT) {
            String[] databaseManagerOptions = ['--url', 'jdbc:hsqldb:mem:devDB', '--noexit'];
            org.hsqldb.util.DatabaseManagerSwing.main(databaseManagerOptions)
        } */
    }
    def destroy = {
    }


}
